'Copyright 2006 James Downey

Imports FetchXML
Imports FetchXMLBuilder.MetadataServiceSdk

Public Class frmLinkedEntity

    Public LinkedEntity As LinkedEntity 'represents the target entity
    Private Entity As EntityMetadata 'represents the source entity

    Public Sub New(ByVal LinkedEntity As LinkedEntity, ByVal Entity As EntityMetadata)
        InitializeComponent()
        If Not LinkedEntity Is Nothing Then
            Me.LinkedEntity = CloneLinkedEntity(LinkedEntity)
        End If
        Me.Entity = Entity
    End Sub

    Private Function CloneLinkedEntity(ByVal Source As LinkedEntity) As LinkedEntity
        Dim Target As New LinkedEntity(Source.Name)
        Target.LinkType = Source.LinkType
        Target.LinkTo = Source.LinkTo
        Target.LinkFrom = Source.LinkFrom
        Target.LinkAlias = Source.LinkAlias
        Target.AllAttributes = Source.AllAttributes
        Target.NoAttributes = Source.NoAttributes
        Dim att, newatt As Attribute
        For Each att In Source.Attributes
            newatt = New Attribute(att.Name)
            newatt.Aggregate = att.Aggregate
            newatt.AttributeAlias = att.AttributeAlias
            Target.Attributes.Add(newatt)
        Next
        Dim order As Order
        For Each order In Source.Orders
            Dim neworder As New Order
            neworder.Attribute = order.Attribute
            neworder.Descending = order.Descending
            Target.Orders.Add(neworder)
        Next
        Dim newfilter, filter As Filter
        Dim condition As Condition
        For Each filter In Source.Filters
            newfilter = New Filter
            newfilter.Type = filter.Type
            For Each condition In filter.Conditions
                Dim newcondition As New Condition
                newcondition.Aggregate = condition.Aggregate
                newcondition.Attribute = condition.Attribute
                newcondition.AttributeAlias = condition.AttributeAlias
                newcondition.ConditionOperator = condition.ConditionOperator
                Dim value As String
                For Each value In condition.Values
                    newcondition.Values.Add(value)
                Next
                newfilter.Conditions.Add(newcondition)
            Next
            Target.Filters.Add(newfilter)
        Next
        Dim lentity, newlinkedentity As LinkedEntity
        For Each lentity In Source.LinkedEntities
            newlinkedentity = CloneLinkedEntity(lentity)
            Target.LinkedEntities.Add(newlinkedentity)
        Next
        Return Target
    End Function

    Private Sub frmLinkedEntity_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        LoadEntities()
        If Not LinkedEntity Is Nothing Then
            LoadTo()
            LoadFrom(Me.LinkedEntity.Name)
            'LoadAttributes(Me.LinkedEntity.Name)
            LoadAttributes()
            LoadOrders()
            LoadFilters()
            LoadLinkedEntities()
            Me.lstEntity.SelectedItem = Me.lstEntity.Items(Me.lstEntity.FindString(Me.LinkedEntity.Name))
            If Not Me.LinkedEntity.LinkType Is Nothing AndAlso Me.LinkedEntity.LinkType.Length > 0 Then
                Me.lstType.SelectedItem = Me.lstType.Items(Me.lstType.FindString(Me.LinkedEntity.LinkType))
            End If
            If Not Me.LinkedEntity.LinkFrom Is Nothing AndAlso Me.LinkedEntity.LinkFrom.Length > 0 Then
                Me.lstFrom.SelectedItem = Me.lstFrom.Items(Me.lstFrom.FindString(Me.LinkedEntity.LinkFrom))
            End If
            If Not Me.LinkedEntity.LinkTo Is Nothing AndAlso Me.LinkedEntity.LinkTo.Length > 0 Then
                Me.lstTo.SelectedItem = Me.lstTo.Items(Me.lstTo.FindString(Me.LinkedEntity.LinkTo))
            End If
            If Not Me.LinkedEntity.LinkAlias Is Nothing Then
                Me.txtAlias.Text = Me.LinkedEntity.LinkAlias
            End If
            Me.chkAllAttributes.Checked = Me.LinkedEntity.AllAttributes
            Me.chkNoAttrib.Checked = Me.LinkedEntity.NoAttributes
            LoadAttributes()
            'If Me.LinkedEntity.AllAttributes = False Then
            '    Dim att As Attribute
            '    For Each att In Me.LinkedEntity.Attributes
            '        Me.lstAttributes.SetItemChecked(Me.lstAttributes.FindString(att.ToString), True)
            '        'TODO: check this code
            '    Next
            'End If
        End If
    End Sub

    Private Sub LoadEntities()
        Me.lstEntity.Items.Clear()
        Dim i As Integer
        For i = 0 To CurrentMetadata.Entities.Length - 1
            Me.lstEntity.Items.Add(CurrentMetadata.Entities(i).Name)
        Next
    End Sub

    Private Sub LoadTo() 'source
        Dim i As Integer
        Me.lstTo.Items.Clear()
        For i = 0 To Entity.Attributes.Length - 1
            Me.lstTo.Items.Add(Entity.Attributes(i).Name)
        Next
    End Sub

    Private Sub LoadFrom(ByVal TargetEntity As String)
        Dim i As Integer
        Me.lstFrom.Items.Clear()
        Dim target As EntityMetadata = GetEntity(TargetEntity)
        For i = 0 To target.Attributes.Length - 1
            Me.lstFrom.Items.Add(target.Attributes(i).Name)
        Next
    End Sub

    'Private Sub LoadAttributes(ByVal TargetEntity As String)
    '    Dim i As Integer
    '    Me.lstAttributes.Items.Clear()
    '    Dim target As EntityMetadata = GetEntity(TargetEntity)
    '    For i = 0 To target.Attributes.Length - 1
    '        Me.lstAttributes.Items.Add(target.Attributes(i).Name)
    '    Next
    'End Sub

    Public Sub LoadAttributes()
        Me.lstAttributes.Items.Clear()
        Dim attrib As Attribute
        For Each attrib In Me.LinkedEntity.Attributes
            Me.lstAttributes.Items.Add(attrib)
        Next
    End Sub

    Private Sub LoadOrders()
        Me.lstOrder.Items.Clear()
        Dim order As Order
        For Each order In Me.LinkedEntity.Orders
            Me.lstOrder.Items.Add(order)
        Next
    End Sub

    Private Sub LoadFilters()
        Me.lstFilters.Items.Clear()
        Dim filter As Filter
        For Each filter In Me.LinkedEntity.Filters
            Me.lstFilters.Items.Add(filter)
        Next
    End Sub

    Private Sub lstEntity_SelectedIndexChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles lstEntity.SelectedIndexChanged
        If Not Me.LinkedEntity Is Nothing AndAlso Me.lstEntity.SelectedItem.ToString <> Me.LinkedEntity.Name Then
            If Windows.Forms.MessageBox.Show("Changing the linked entity will invalidate the other data collected on this form.", Application.ProductName, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
                Me.lstEntity.SelectedItem = Me.lstEntity.Items(Me.lstEntity.FindString(Me.LinkedEntity.Name))
                Exit Sub
            End If
        End If
        If Me.LinkedEntity Is Nothing OrElse Me.lstEntity.SelectedItem.ToString <> Me.LinkedEntity.Name Then
            Me.LinkedEntity = New LinkedEntity(Me.lstEntity.SelectedItem.ToString)
            LoadTo()
            LoadFrom(Me.lstEntity.SelectedItem.ToString)
            'LoadAttributes(Me.lstEntity.SelectedItem.ToString)
            LoadAttributes()
            LoadOrders()
            LoadFilters()
        End If
    End Sub

    Private Sub btnCancel_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCancel.Click
        Me.DialogResult = Windows.Forms.DialogResult.Cancel
        Me.Close()
    End Sub

    Private Sub btnOK_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnOK.Click
        If Me.lstTo.SelectedIndex > -1 Then Me.LinkedEntity.LinkTo = Me.lstTo.SelectedItem.ToString
        If Me.lstFrom.SelectedIndex > -1 Then Me.LinkedEntity.LinkFrom = Me.lstFrom.SelectedItem.ToString
        If Not Me.lstType.SelectedIndex = -1 Then Me.LinkedEntity.LinkType = Me.lstType.SelectedItem.ToString
        Me.LinkedEntity.LinkAlias = Me.txtAlias.Text
        Me.LinkedEntity.AllAttributes = Me.chkAllAttributes.Checked
        If Not Me.chkAllAttributes.Checked Then
            Dim att As Attribute
            Me.LinkedEntity.Attributes.Clear()
            For Each att In Me.lstAttributes.Items
                Me.LinkedEntity.Attributes.Add(att)
            Next
        End If

        Me.DialogResult = Windows.Forms.DialogResult.OK
        Me.Close()
    End Sub

    Private Sub btnEditOrder_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEditOrder.Click
        If Me.lstEntity.SelectedIndex = -1 Then
            Windows.Forms.MessageBox.Show("Select an entity.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Exit Sub
        End If
        Dim frm As New frmOrder(Me.LinkedEntity.Orders, GetEntity(Me.LinkedEntity.Name))
        If frm.ShowDialog = Windows.Forms.DialogResult.OK Then
            LoadOrders()
        End If
    End Sub

    Private Sub btnAddFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddFilter.Click
        If Me.lstEntity.SelectedIndex = -1 Then
            Windows.Forms.MessageBox.Show("Select an entity.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Exit Sub
        End If
        Dim filter As New Filter()
        Dim frmFilter As New frmFilter(filter, GetEntity(Me.LinkedEntity.Name))
        If frmFilter.ShowDialog() = Windows.Forms.DialogResult.OK Then
            Me.LinkedEntity.Filters.Add(filter)
        End If
        LoadFilters()
    End Sub

    Private Sub btnEditFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEditFilter.Click
        If Me.lstFilters.SelectedIndex = -1 Then
            Windows.Forms.MessageBox.Show("Select a filter.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Exit Sub
        End If
        Dim filter As Filter = Me.lstFilters.SelectedItem
        Dim frmFilter As New frmFilter(filter, GetEntity(Me.LinkedEntity.Name))
        If frmFilter.ShowDialog() = Windows.Forms.DialogResult.OK Then
            LoadFilters()
        End If
    End Sub

    Private Sub btnDeleteFilter_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeleteFilter.Click
        If Me.lstFilters.SelectedItem Is Nothing Then
            Windows.Forms.MessageBox.Show("Select a filter.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Exit Sub
        End If
        If Windows.Forms.MessageBox.Show("Are you sure that you want to delete this filter?", Application.ProductName, MessageBoxButtons.YesNo, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Yes Then
            Me.LinkedEntity.Filters.Remove(Me.lstFilters.SelectedItem)
            LoadFilters()
        End If
    End Sub

    Private Sub btnRelationship_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnRelationship.Click
        If Not Me.lstEntity.SelectedIndex = -1 Then
            If Windows.Forms.MessageBox.Show("Changing the linked entity will invalidate the other data collected on this form.", Application.ProductName, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.Cancel Then
                Exit Sub
            End If
        End If
        Dim frm As New frmRelationship(Me.Entity)
        If frm.ShowDialog = Windows.Forms.DialogResult.OK Then
            'Me.LinkedEntity = Nothing
            'Me.lstEntity.SelectedIndex = -1
            If frm.RelationshipType = RelationshipType.FromRelationship Then
                Me.lstEntity.SelectedItem = Me.lstEntity.Items(Me.lstEntity.FindString(frm.Relationship.ReferencedEntity))
                Me.lstTo.SelectedItem = Me.lstTo.Items(Me.lstTo.FindString(frm.Relationship.ReferencingAttribute)) 'source
                Me.lstFrom.SelectedItem = Me.lstFrom.Items(Me.lstFrom.FindString(frm.Relationship.ReferencedAttribute)) 'target
            Else
                Me.lstEntity.SelectedItem = Me.lstEntity.Items(Me.lstEntity.FindString(frm.Relationship.ReferencingEntity))
                Me.lstTo.SelectedItem = Me.lstTo.Items(Me.lstTo.FindString(frm.Relationship.ReferencedAttribute)) 'source
                Me.lstFrom.SelectedItem = Me.lstFrom.Items(Me.lstFrom.FindString(frm.Relationship.ReferencingAttribute)) 'targer
            End If
        End If
    End Sub

    Private Sub btnAttributes_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAttributes.Click
        Dim frmAttrib As New frmAttribute(Me.LinkedEntity)
        If frmAttrib.ShowDialog = Windows.Forms.DialogResult.OK Then
            LoadAttributes()
        End If
    End Sub

    'Public Sub LoadAttributes()
    '    Me.lstAttributes.Items.Clear()
    '    Dim attrib As Attribute
    '    For Each attrib In Me.LinkedEntity.Attributes
    '        Me.lstAttributes.Items.Add(attrib)
    '    Next
    'End Sub

    Public Sub LoadLinkedEntities()
        Me.lstLinks.Items.Clear()
        Dim link As LinkedEntity
        For Each link In Me.LinkedEntity.LinkedEntities
            Me.lstLinks.Items.Add(link)
        Next
    End Sub

    Private Sub btnAddLinkElement_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnAddLinkElement.Click
        Dim frm As New frmLinkedEntity(Nothing, GetEntity(Me.LinkedEntity.Name))
        If frm.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.LinkedEntity.LinkedEntities.Add(frm.LinkedEntity)
            LoadLinkedEntities()
        End If
    End Sub

    Private Sub btnEditLinkElement_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnEditLinkElement.Click
        If Me.lstLinks.SelectedIndex = -1 Then
            Windows.Forms.MessageBox.Show("Select a linked-entity.", Application.ProductName, MessageBoxButtons.OK, MessageBoxIcon.Exclamation)
            Exit Sub
        End If
        Dim frm As New frmLinkedEntity(Me.lstLinks.SelectedItem, GetEntity(Me.LinkedEntity.Name))
        If frm.ShowDialog = Windows.Forms.DialogResult.OK Then
            Me.LinkedEntity.LinkedEntities.Replace(Me.lstLinks.SelectedItem, frm.LinkedEntity)
            LoadLinkedEntities()
        End If
    End Sub

    Private Sub btnDeleteLink_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnDeleteLink.Click
        If Me.lstLinks.SelectedIndex = -1 Then Exit Sub
        If Windows.Forms.MessageBox.Show("Are you sure that you want to delete this linked-entity?", Application.ProductName, MessageBoxButtons.OKCancel, MessageBoxIcon.Question) = Windows.Forms.DialogResult.OK Then
            Me.LinkedEntity.LinkedEntities.Remove(Me.lstLinks.SelectedItem)
            LoadLinkedEntities()
        End If
    End Sub

End Class

